package org.example.testdemo.controller;

import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.constraints.NotNull;
import org.example.testdemo.pojo.*;
import org.example.testdemo.pojo.combination.DeclareInformation;
import org.example.testdemo.pojo.combination.ProjectUpdate;
import org.example.testdemo.service.AccountingIntervalService;
import org.example.testdemo.service.DeclareService;
import org.example.testdemo.service.FinancialYearService;
import org.example.testdemo.service.ProjectService;
import org.example.testdemo.tool.ApiResponse;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.time.LocalDateTime;

@RestController
@RequestMapping("declare")
@Validated
public class DeclareController {

    @Resource
    private DeclareService declareService;

    @Resource
    private FinancialYearService financialYearService;

    @Resource
    private AccountingIntervalService intervalService;

    @Resource
    private ProjectService projectService;

    @PostMapping("addDeclare")
    public ApiResponse addDeclare(@Validated Declare declare, HttpServletRequest request){
        System.out.println(declare.toString());
        LocalDateTime localDateTime = LocalDateTime.now();
        //获取年份
        String year = String.valueOf(localDateTime.getYear());
        //获取月分
        String month = String.valueOf(localDateTime.getMonthValue());
        //查询年度信息
        FinancialYear serviceByYearId = financialYearService.findByYearId(year);
        if(serviceByYearId==null){
            //新增年度信息
            FinancialYear financialYear = new FinancialYear(year,year+"年",localDateTime,localDateTime);
            Integer integer = financialYearService.addFinancialYear(financialYear);
            if(integer<1){
                return ApiResponse.fail(20000,"新增申报信息失败");
            }
            serviceByYearId = financialYear;
        }
        declare.setYearId(serviceByYearId.getYearId());
        //获取会计区间
        AccountingInterval intervalId = intervalService.findByIntervalId(month.length() == 2 ? month : "0" + month);
        if(intervalId == null){
            return ApiResponse.fail(20000,"新增申报信息失败");
        }
        declare.setIntervalId(intervalId.getIntervalId());
        //获取项目信息
        Project project = projectService.querySubordinateProjects(declare.getPId());
        if(project==null){
            return ApiResponse.fail(20000,"新增申报信息失败");
        }
        //获取状态不为通过的申报信息
        BigDecimal amount = declareService.getAmount(project.getPId());
        if(amount!=null){
            project.setBalance(project.getBalance().subtract(amount));
        }
        if(project.getBalance().compareTo(declare.getMoney()) < 0){
            return ApiResponse.fail(20000,"项目金额不足，请选择其他项目");
        }
        //获取用户id
        String userId = (String) request.getSession().getAttribute("userId");
        declare.setUserId(userId);
        declare.setCreationTime(localDateTime);
        declare.setChangeTime(localDateTime);
        declare.setSupplement(declare.getSupplement().isEmpty()?"无":declare.getSupplement());
        System.out.println(declare);
        //新增申报信息
        Integer integer = declareService.addDeclare(declare);
        if(integer<1){
            return ApiResponse.fail(20000,"新增申报信息失败");
        }
        return ApiResponse.success();
    }


    @PostMapping("getDeclareInformation")
    public ApiResponse getDeclareInformation(String pId, String yearId,
                                             String intervalId, @NotNull(message = "参数异常") Integer state, PageReq pageReq,HttpServletRequest request){
        if (null == yearId || yearId.isEmpty()) {
            yearId = null;
        }
        if (null == intervalId || intervalId.isEmpty()) {
            intervalId = null;
        }
        if (null == pId || pId.isEmpty()) {
            pId = null;
        }
        pageReq.setSize(10);
        return ApiResponse.success(declareService.getDeclareInformation(pId,yearId,intervalId,state,pageReq,(String) request.getSession().getAttribute("userId")));
    }

    @PostMapping("declareSubmit")
    public ApiResponse declareSubmit(@NotNull(message = "参数异常") String declareId,HttpServletRequest request){
        //获取申报id
        Declare declare = declareService.findByDeclareId(declareId);
        if(declare==null){
            return ApiResponse.error();
        }
        //获取用户id
        String userId = (String) request.getSession().getAttribute("userId");
        if(!userId.equals(declare.getUserId())){
            return ApiResponse.fail(20000,"无权限操作此申报");
        }
        if(declare.getState()!=1 && declare.getState()!=3){
            return ApiResponse.fail(20000,"此状态无法送审");
        }
        //修改申报状态
        declare.setState(2);
        declare.setChangeTime(LocalDateTime.now());
        Integer state = declareService.updateState(declare);
        if(state<1){
            return ApiResponse.fail(20000,"送审操作失败");
        }
        return ApiResponse.success();
    }

    @PostMapping("revokeSubmit")
    public ApiResponse revokeSubmit(@NotNull(message = "参数异常") String declareId,HttpServletRequest request){
        //获取申报id
        Declare declare = declareService.findByDeclareId(declareId);
        if(declare==null){
            return ApiResponse.error();
        }
        //获取用户id
        String userId = (String) request.getSession().getAttribute("userId");
        if(!userId.equals(declare.getUserId())){
            return ApiResponse.fail(20000,"无权限操作此申报");
        }
        if(declare.getState()!=2){
            return ApiResponse.fail(20000,"此状态无法撤销");
        }
        //修改申报状态
        declare.setState(1);
        declare.setChangeTime(LocalDateTime.now());
        Integer state = declareService.updateState(declare);
        if(state<1){
            return ApiResponse.fail(20000,"撤销送审操作失败");
        }
        return ApiResponse.success();
    }

    @PostMapping("deleteDeclare")
    public ApiResponse deleteDeclare(@NotNull(message = "参数异常") String declareId,HttpServletRequest request){
        //获取申报id
        Declare declare = declareService.findByDeclareId(declareId);
        if(declare==null){
            return ApiResponse.error();
        }
        //获取用户id
        String userId = (String) request.getSession().getAttribute("userId");
        if(!userId.equals(declare.getUserId())){
            return ApiResponse.fail(20000,"无权限操作此申报");
        }
        if(declare.getState()!=1 && declare.getState()!=3){
            return ApiResponse.fail(20000,"此状态无法删除申报");
        }
        //删除申报
        Integer deleted = declareService.deleteDeclare(declareId);
        if(deleted<1){
            return ApiResponse.fail(20000,"删除申报失败");
        }
        return ApiResponse.success();
    }

    @PostMapping("getDeclareInformationSingle")
    public ApiResponse getDeclareInformationSingle(@NotNull(message = "参数异常") String declareId,HttpServletRequest request){
        //获取申报id
        Declare declare = declareService.findByDeclareId(declareId);
        if(declare==null){
            return ApiResponse.error();
        }
        //获取用户id
        String userId = (String) request.getSession().getAttribute("userId");
        if(!userId.equals(declare.getUserId())){
            return ApiResponse.fail(20000,"无权限操作此申报");
        }
        //查询申报信息
        DeclareInformation single = declareService.getDeclareInformationSingle(declareId);
        return ApiResponse.success(single);
    }

    @PostMapping("updateDeclare")
    public ApiResponse updateDeclare(@Validated Declare declare, HttpServletRequest request){
        if(declare.getDeclareId() == null || declare.getDeclareId().isEmpty()){
            return ApiResponse.fail(20000,"参数异常");
        }
        //获取申报id
        Declare declare1 = declareService.findByDeclareId(declare.getDeclareId());
        if(declare1==null){
            return ApiResponse.error();
        }
        //获取用户id
        String userId = (String) request.getSession().getAttribute("userId");
        if(!userId.equals(declare1.getUserId())){
            return ApiResponse.fail(20000,"无权限操作此申报");
        }
        //判断申报状态
        if(declare1.getState()!=1 && declare1.getState()!=3){
            return ApiResponse.fail(20000,"此状态无法修改申报");
        }
        //获取项目信息
        Project project = projectService.querySubordinateProjects(declare.getPId());
        if(project==null){
            return ApiResponse.fail(20000,"新增申报信息失败");
        }
        //获取状态不为通过的申报信息
        BigDecimal amount = declareService.getAmount(project.getPId());
        if(amount!=null){
            project.setBalance(project.getBalance().subtract(amount).add(declare1.getMoney()));
        }
        if(project.getBalance().compareTo(declare.getMoney()) < 0){
            return ApiResponse.fail(20000,"项目金额不足，请选择其他项目");
        }
        declare1.setDeclareName(declare.getDeclareName());
        declare1.setPhone(declare.getPhone());
        declare1.setMoney(declare.getMoney());
        declare1.setPId(declare.getPId());
        declare1.setSupplement(declare.getSupplement());

        Integer updated = declareService.updateDeclare(declare1);
        if(updated<1){
            return ApiResponse.fail(20000,"修改申报失败");
        }
        return ApiResponse.success();
    }

    @PostMapping("findByDeclareInformationAll")
    public ApiResponse findByDeclareInformationAll(String pId, String yearId,
                                             String intervalId, @NotNull(message = "参数异常") Integer state, PageReq pageReq,HttpServletRequest request){
        if (null == yearId || yearId.isEmpty()) {
            yearId = null;
        }
        if (null == intervalId || intervalId.isEmpty()) {
            intervalId = null;
        }
        if (null == pId || pId.isEmpty()) {
            pId = null;
        }
        if(state!=2 && state!=3 && state!=4){
            return ApiResponse.fail(20000,"异常访问");
        }
        pageReq.setSize(10);
        return ApiResponse.success(declareService.findByDeclareInformationAll(pId,yearId,intervalId,state,pageReq,(String) request.getSession().getAttribute("userId")));
    }

    @PostMapping("rejectDeclare")
    public ApiResponse rejectDeclare(@NotNull(message = "参数异常") String declareId,HttpServletRequest request){
        //获取申报id
        Declare declare = declareService.findByDeclareId(declareId);
        if(declare==null){
            return ApiResponse.error();
        }
        Project project = projectService.searchResponsiblePerson(declare.getPId(), (String) request.getSession().getAttribute("userId"));
        if(project == null){
            return ApiResponse.fail(20000,"无权限操作此申报");
        }
        if(declare.getState()!=2){
            return ApiResponse.fail(20000,"此状态无法驳回申报");
        }
        //驳回申报
        declare.setState(3);
        declare.setReviewer(project.getUserId());
        Integer updated = declareService.updateDeclare(declare);
        if(updated<1){
            return ApiResponse.fail(20000,"驳回申报失败");
        }
        return ApiResponse.success();
    }

    @PostMapping("declareSuccess")
    @Transactional
    public ApiResponse declareSuccess(@NotNull(message = "参数异常") String declareId,HttpServletRequest request){
        //获取申报id
        Declare declare = declareService.findByDeclareId(declareId);
        if(declare==null){
            return ApiResponse.error();
        }
        Project project = projectService.searchResponsiblePerson(declare.getPId(), (String) request.getSession().getAttribute("userId"));
        if(project == null){
            return ApiResponse.fail(20000,"无权限操作此申报");
        }
        if(declare.getState()!=2){
            return ApiResponse.fail(20000,"此状态无法通过申报");
        }
        project.setExpenses(project.getExpenses().add(declare.getMoney()));
        project.setBalance(project.getBalance().subtract(declare.getMoney()));
        //修改状态
        declare.setState(4);
        Integer updated = declareService.updateDeclare(declare);
        if(updated<1){
            return ApiResponse.fail(20000,"通过申报失败");
        }
        //修改数据库金额
        Integer updateProject = projectService.updateProject(project);
        if(updateProject<1){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ApiResponse.fail(20000,"通过申报失败");
        }
        return ApiResponse.success();
    }

    @PostMapping("revokeSuccess")
    @Transactional
    public ApiResponse revokeSuccess(@NotNull(message = "参数异常") String declareId,HttpServletRequest request){
        //获取申报id
        Declare declare = declareService.findByDeclareId(declareId);
        if(declare==null){
            return ApiResponse.error();
        }
        Project project = projectService.searchResponsiblePerson(declare.getPId(), (String) request.getSession().getAttribute("userId"));
        if(project == null){
            return ApiResponse.fail(20000,"无权限操作此申报");
        }
        if(declare.getState()!=4){
            return ApiResponse.fail(20000,"此状态无法撤销申报");
        }
        project.setExpenses(project.getExpenses().subtract(declare.getMoney()));
        project.setBalance(project.getBalance().add(declare.getMoney()));
        //修改状态
        declare.setState(2);
        Integer updated = declareService.updateDeclare(declare);
        if(updated<1){
            return ApiResponse.fail(20000,"撤销申报失败");
        }
        //修改数据库金额
        Integer updateProject = projectService.updateProject(project);
        if(updateProject<1){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ApiResponse.fail(20000,"撤销申报失败");
        }
        return ApiResponse.success();
    }

}
